package vip.xiaonuo.biz.modular.event.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import vip.xiaonuo.biz.modular.apilog.entity.DevApiLog;
import vip.xiaonuo.biz.modular.apilog.mapper.DevApiLogMapper;
import vip.xiaonuo.biz.modular.cabinetdoor.mapper.BizCabinetDoorMapper;
import vip.xiaonuo.biz.modular.cabinetdoor.vo.BizCabinetDoorResp;
import vip.xiaonuo.biz.modular.event.entity.BizEvent;
import vip.xiaonuo.biz.modular.event.entity.BizEventConfig;
import vip.xiaonuo.biz.modular.event.mapper.BizEventConfigMapper;
import vip.xiaonuo.biz.modular.event.mapper.BizEventMapper;
import vip.xiaonuo.biz.modular.event.service.BizEventGoodsService;
import vip.xiaonuo.biz.modular.event.service.BizEventReagentService;
import vip.xiaonuo.biz.modular.event.service.BizEventReplaceService;
import vip.xiaonuo.biz.modular.event.util.EventActionUtil;
import vip.xiaonuo.biz.modular.goods.entity.BizGoods;
import vip.xiaonuo.biz.modular.goods.entity.BizGoodsLedger;
import vip.xiaonuo.biz.modular.goods.mapper.BizGoodsLedgerMapper;
import vip.xiaonuo.biz.modular.goods.mapper.BizGoodsMapper;
import vip.xiaonuo.biz.modular.goods.result.GoodsLedgerPageResult;
import vip.xiaonuo.biz.modular.goods.service.BizGoodsLedgerCheckService;
import vip.xiaonuo.biz.modular.goods.service.BizGoodsService;
import vip.xiaonuo.common.util.AliyunSmsUtil;
import vip.xiaonuo.common.util.CommonListUtil;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class BizEventGoodsServiceImpl implements BizEventGoodsService {

    @Resource
    private BizGoodsMapper bizGoodsMapper;

    @Resource
    private BizGoodsService bizGoodsService;

    @Resource
    private BizEventConfigMapper bizEventConfigMapper;

    @Resource
    private BizEventReplaceService bizEventReplaceService;

    @Resource
    private BizEventMapper bizEventMapper;

    @Resource
    private BizCabinetDoorMapper bizCabinetDoorMapper;

    @Resource
    private DevApiLogMapper devApiLogMapper;

    @Resource
    private BizGoodsLedgerMapper bizGoodsLedgerMapper;

    @Resource
    private BizGoodsLedgerCheckService bizGoodsLedgerCheckService;

    @Resource
    private BizEventReagentService bizEventReagentService;

    @Override
    public void handleGoods(DevApiLog apiLog) {
        if (StringUtils.isNotBlank(apiLog.getRfids())) {
            //原始rfids
            List<String> origRfids = Arrays.asList(apiLog.getRfids().split(","));
            //根据rfids获取物品列表
            List<BizGoods> goodsList = bizGoodsMapper.getListByRfids(origRfids);
            //过滤rfids
            List<String> ftlrRfids = goodsList.stream().map(e -> e.getRfidNum()).collect(Collectors.toList());
            //对比差异部分
            Map<Boolean, List<String>> contrastList = CommonListUtil.contrastList(origRfids, ftlrRfids);
            //新增部分
            List<String> newRfids = contrastList.get(false);
            //存在部分
            List<String> oldRfids = contrastList.get(true);
            //新物品事件部分
            this.addNewGoods(newRfids, apiLog);
            //获取柜子信息
            BizCabinetDoorResp cabinetDoorResp = bizCabinetDoorMapper.getInfoByCabCodeAndCabDoorCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            //更新当前物品所在柜子信息
            if (!CollectionUtils.isEmpty(newRfids)) {
                bizGoodsMapper.updateCabInfoForNewGoodsByRfids(newRfids, cabinetDoorResp.getCabinetGroupId(), cabinetDoorResp.getCabinetInfoId(), cabinetDoorResp.getId());
            }
            if (!CollectionUtils.isEmpty(oldRfids)) {
                bizGoodsMapper.updateCabInfoForGoodsByRfids(oldRfids, cabinetDoorResp.getCabinetGroupId(), cabinetDoorResp.getCabinetInfoId(), cabinetDoorResp.getId());
                bizGoodsMapper.updateStoAbcForGoodsByRfids(oldRfids);
                bizGoodsMapper.updateToStoAbcForGoodsByRfids(origRfids);
            }
            //获取物品未入柜的列表
            List<BizGoods> notInCabList = goodsList.stream().filter(item -> item.getEnterFlag() == 0).collect(Collectors.toList());
            //首次入柜事件
            this.addRecordForGoodsFirstInCab(notInCabList, apiLog);
            //处理试剂首次入库事件
            bizEventReagentService.handleReagentInCabFirst(apiLog);
            //更新物品入库标识
            bizGoodsMapper.updateEnterFlagByRfids(origRfids);
            //针对所属柜子信息为空情况下-更新物品所属柜子信息
            for (BizGoods goods : goodsList) {
                if (StringUtils.isBlank(goods.getBioCabinetDoorId()) && StringUtils.isBlank(goods.getBioCabinetId()) && StringUtils.isBlank(goods.getBioCabinetGroupId())) {
                    bizGoodsMapper.updateCabInfoForGoodsId(goods.getId(), cabinetDoorResp.getCabinetGroupId(), cabinetDoorResp.getCabinetInfoId(), cabinetDoorResp.getId());
                }
            }
        }
        //处理物品动作
        this.handleGoodsAction(apiLog);
        //处理试剂-试剂存储属性冲突
        bizEventReagentService.handleReagentClassClash(apiLog);
    }

    /**
     * 处理物品动作
     *
     * @param apiLog
     */
    private void handleGoodsAction(DevApiLog apiLog) {
        if (StringUtils.isNotBlank(apiLog.getRelationId())) {
            //历史关联的api数据
            DevApiLog relationApiLog = devApiLogMapper.selectById(apiLog.getRelationId());
            if (null != relationApiLog) {
                //获取新增部分
                List<String> addList = CommonListUtil.getAddaListThanbList(Arrays.asList(apiLog.getRfids().split(",")), Arrays.asList(relationApiLog.getRfids().split(",")));
                addList = addList.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
                //获取减少部分
                List<String> reduceList = CommonListUtil.getReduceaListThanbList(Arrays.asList(apiLog.getRfids().split(",")), Arrays.asList(relationApiLog.getRfids().split(",")));
                reduceList = reduceList.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
                //记录-维修中物品出柜 22
                this.addRecordForRepariGoodsOutCab(reduceList, apiLog);
                //记录-报废物品出柜 23
                this.addRecordForScrapiGoodsOutCab(reduceList, apiLog);
                //记录-报废物品入柜 25
                this.addRecordForScrapiGoodsInCab(addList, apiLog);
                //记录-取还柜不一致 17
                this.addRecordForGoodsInWrongCab(addList, apiLog);
                //物品-归还
                this.handleForGoodsReturn(addList, apiLog);
                //处理试剂-试剂柜超过最大承重
                bizEventReagentService.handleCabWeight(addList, apiLog);
                //物品-借出
                this.handleGoodsBorrow(reduceList, apiLog);
            }
        }else{
            //针对突发情况 非连续性开关门【如 钥匙开锁】 针对物品进行归还补偿操作
            List<String> origRfids = Arrays.asList(apiLog.getRfids().split(","));
            if(!CollectionUtils.isEmpty(origRfids)){
                this.handleForGoodsReturn(origRfids, apiLog);
            }
        }
    }

    /**
     * 新增未知物品
     *
     * @param rfids
     * @param apiLog
     */
    private void addNewGoods(List<String> rfids, DevApiLog apiLog) {
        if (!CollectionUtils.isEmpty(rfids)) {
            //获取柜子信息
            BizCabinetDoorResp bizCabinetDoorResp = bizCabinetDoorMapper.getInfoByCabCodeAndCabDoorCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            Integer goodsType = 0;
            if (null != bizCabinetDoorResp) {
                goodsType = bizCabinetDoorResp.getCabinetDoorType();
            }
            List<BizGoods> goodsList = new ArrayList<>();
            for (String rfid : rfids) {
                BizGoods item = new BizGoods();
                item.setGoodsType(goodsType);
                item.setRfidFlag(1);
                item.setRfidNum(rfid);
                item.setUnknownFlag(1);
                item.setCreateUser(apiLog.getUserId());
                goodsList.add(item);
            }
            //批量新增未知的物品
            bizGoodsService.saveBatch(goodsList);
            //首次入柜事件
            this.addRecordForGoodsFirstInCab(goodsList, apiLog);
            //未知物品事件
            this.addRecordForUnknowGoodsInCab(goodsList, apiLog);
        }
    }

    /**
     * 添加记录-首次入柜
     *
     * @param goodsList
     * @param apiLog
     */
    private void addRecordForGoodsFirstInCab(List<BizGoods> goodsList, DevApiLog apiLog) {
        //查询对应配置
        BizEventConfig eventConfig = bizEventConfigMapper.selectById("16");
        //柜门名称
        String doorName = bizEventReplaceService.getCbaDoorNameForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        for (BizGoods goods : goodsList) {
            String eventDesc = eventConfig.getEventDesc();
            //事件描述
            String goodsName = bizEventReplaceService.getGoodsNameForEntity(goods);
            eventDesc = eventDesc.replace("{{goods}}", goodsName);
            eventDesc = eventDesc.replace("{{cab-door}}", doorName);
            eventDesc = eventDesc.replace("{{time}}", DateUtil.formatDateTime(apiLog.getEventTime()));
            eventDesc = eventDesc.replace("{{action}}", EventActionUtil.getApiAction(apiLog.getReqType()));
            String userName = bizEventReplaceService.getUserName(apiLog.getUserId());
            eventDesc = eventDesc.replace("{{user}}", userName);
            //组合实体类
            BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
            event.setApiLogId(apiLog.getId());
            event.setEventConfigId(eventConfig.getId());
            event.setEventTime(apiLog.getEventTime());
            event.setEventDesc(eventDesc);
            event.setEventUserId(apiLog.getUserId());
            event.setGoodsId(goods.getId());
            event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
            event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
            event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
            event.setCabinetDoorId(cabinetDoorResp.getId());
            bizEventReplaceService.clearBizEvent(event);
            //类目切换
            bizEventReplaceService.itemSwitch(event, goods.getGoodsType());
            bizEventMapper.insert(event);
            //记录台账-首次入柜
            bizGoodsService.handleLedgerForEventOfGoodsInCab(goods, apiLog);

            //【邮件】本次刷卡开门的卡主，柜门管理员
            bizEventReplaceService.sendEmailForUser(apiLog.getUserId(), event);
            bizEventReplaceService.sendEmailForDoorAdmin(event);
        }
    }

    /**
     * 添加记录-未知物品入柜
     *
     * @param goodsList
     * @param apiLog
     */
    private void addRecordForUnknowGoodsInCab(List<BizGoods> goodsList, DevApiLog apiLog) {
        //查询对应配置
        BizEventConfig eventConfig = bizEventConfigMapper.selectById("26");
        //柜门名称
        String doorName = bizEventReplaceService.getCbaDoorNameForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
        for (BizGoods goods : goodsList) {
            String eventDesc = eventConfig.getEventDesc();
            //事件描述
            eventDesc = eventDesc.replace("{{cab-door}}", doorName);
            eventDesc = eventDesc.replace("{{time}}", DateUtil.formatDateTime(apiLog.getEventTime()));
            eventDesc = eventDesc.replace("{{action}}", EventActionUtil.getApiAction(apiLog.getReqType()));
            String userName = bizEventReplaceService.getUserName(apiLog.getUserId());
            eventDesc = eventDesc.replace("{{user}}", userName);
            //组合实体类
            BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
            event.setApiLogId(apiLog.getId());
            event.setEventConfigId(eventConfig.getId());
            event.setEventTime(apiLog.getEventTime());
            event.setEventDesc(eventDesc);
            event.setEventUserId(apiLog.getUserId());
            event.setGoodsId(goods.getId());
            event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
            event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
            event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
            event.setCabinetDoorId(cabinetDoorResp.getId());
            bizEventReplaceService.clearBizEvent(event);
            //类目切换
            bizEventReplaceService.itemSwitch(event, goods.getGoodsType());
            bizEventMapper.insert(event);

            //【邮件】本次刷卡开门的卡主，柜门管理员
            bizEventReplaceService.sendEmailForUser(apiLog.getUserId(), event);
            bizEventReplaceService.sendEmailForDoorAdmin(event);

        }
    }

    /**
     * 添加记录-维修中物品出柜
     *
     * @param rfids
     * @param apiLog
     */
    private void addRecordForRepariGoodsOutCab(List<String> rfids, DevApiLog apiLog) {
        //关门动作+不为空
        if (apiLog.getReqType() == 2 && !CollectionUtils.isEmpty(rfids)) {
            //查询对应配置
            BizEventConfig eventConfig = bizEventConfigMapper.selectById("22");
            List<BizGoods> goodsList = bizGoodsMapper.getListByRfids(rfids);
            //柜门信息
            BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            for (BizGoods goods : goodsList) {
                if (goods.getState() == 2) {
                    String eventDesc = eventConfig.getEventDesc();
                    //事件描述
                    eventDesc = eventDesc.replace("{{goods}}", bizEventReplaceService.getGoodsNameForEntity(goods));
                    eventDesc = eventDesc.replace("{{time}}", DateUtil.formatDateTime(apiLog.getEventTime()));
                    String userName = bizEventReplaceService.getUserName(apiLog.getUserId());
                    eventDesc = eventDesc.replace("{{user}}", userName);
                    //组合实体类
                    BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
                    event.setApiLogId(apiLog.getId());
                    event.setEventConfigId(eventConfig.getId());
                    event.setEventTime(apiLog.getEventTime());
                    event.setEventDesc(eventDesc);
                    event.setEventUserId(apiLog.getUserId());
                    event.setGoodsId(goods.getId());
                    event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
                    event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
                    event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
                    event.setCabinetDoorId(cabinetDoorResp.getId());
                    bizEventReplaceService.clearBizEvent(event);
                    bizEventMapper.insert(event);

                    //【邮件】本次刷卡开门的卡主，柜子管理员
                    bizEventReplaceService.sendEmailForUser(apiLog.getUserId(), event);
                    bizEventReplaceService.sendEmailForDoorAdmin(event);
                }
            }
        }
    }

    /**
     * 添加记录-报废物品出柜
     *
     * @param rfids
     * @param apiLog
     */
    private void addRecordForScrapiGoodsOutCab(List<String> rfids, DevApiLog apiLog) {
        //关门动作+不为空
        if (apiLog.getReqType() == 2 && !CollectionUtils.isEmpty(rfids)) {
            //查询对应配置
            BizEventConfig eventConfig = bizEventConfigMapper.selectById("23");
            List<BizGoods> goodsList = bizGoodsMapper.getListByRfids(rfids);
            //柜门信息
            BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            for (BizGoods goods : goodsList) {
                if (goods.getState() == 0) {
                    String eventDesc = eventConfig.getEventDesc();
                    //事件描述
                    eventDesc = eventDesc.replace("{{goods}}", bizEventReplaceService.getGoodsNameForEntity(goods));
                    eventDesc = eventDesc.replace("{{time}}", DateUtil.formatDateTime(apiLog.getEventTime()));
                    String userName = bizEventReplaceService.getUserName(apiLog.getUserId());
                    eventDesc = eventDesc.replace("{{user}}", userName);
                    //组合实体类
                    BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
                    event.setApiLogId(apiLog.getId());
                    event.setEventConfigId(eventConfig.getId());
                    event.setEventTime(apiLog.getEventTime());
                    event.setEventDesc(eventDesc);
                    event.setEventUserId(apiLog.getUserId());
                    event.setGoodsId(goods.getId());
                    event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
                    event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
                    event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
                    event.setCabinetDoorId(cabinetDoorResp.getId());
                    bizEventReplaceService.clearBizEvent(event);
                    //类目切换
                    bizEventReplaceService.itemSwitch(event, goods.getGoodsType());
                    bizEventMapper.insert(event);

                    //【邮件】本次刷卡开门的卡主，柜子管理员
                    bizEventReplaceService.sendEmailForUser(apiLog.getUserId(), event);
                    bizEventReplaceService.sendEmailForDoorAdmin(event);
                }
            }
        }
    }

    /**
     * 添加记录-报废物品入柜
     *
     * @param rfids
     * @param apiLog
     */
    private void addRecordForScrapiGoodsInCab(List<String> rfids, DevApiLog apiLog) {
        //关门动作+不为空
        if (apiLog.getReqType() == 2 && !CollectionUtils.isEmpty(rfids)) {
            //查询对应配置
            BizEventConfig eventConfig = bizEventConfigMapper.selectById("25");
            List<BizGoods> goodsList = bizGoodsMapper.getListByRfids(rfids);
            //柜门信息
            BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            for (BizGoods goods : goodsList) {
                if (goods.getState() == 0) {
                    String eventDesc = eventConfig.getEventDesc();
                    //事件描述
                    eventDesc = eventDesc.replace("{{goods}}", bizEventReplaceService.getGoodsNameForEntity(goods));
                    eventDesc = eventDesc.replace("{{time}}", DateUtil.formatDateTime(apiLog.getEventTime()));
                    String userName = bizEventReplaceService.getUserName(apiLog.getUserId());
                    eventDesc = eventDesc.replace("{{user}}", userName);
                    //柜门名称
                    String doorName = bizEventReplaceService.getCbaDoorNameForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
                    eventDesc = eventDesc.replace("{{cab-door}}", doorName);
                    //组合实体类
                    BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
                    event.setApiLogId(apiLog.getId());
                    event.setEventConfigId(eventConfig.getId());
                    event.setEventTime(apiLog.getEventTime());
                    event.setEventDesc(eventDesc);
                    event.setEventUserId(apiLog.getUserId());
                    event.setGoodsId(goods.getId());
                    event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
                    event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
                    event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
                    event.setCabinetDoorId(cabinetDoorResp.getId());
                    bizEventReplaceService.clearBizEvent(event);
                    //类目切换
                    bizEventReplaceService.itemSwitch(event, goods.getGoodsType());
                    bizEventMapper.insert(event);

                    //【邮件】本次刷卡开门的卡主，柜门管理员
                    bizEventReplaceService.sendEmailForUser(apiLog.getUserId(), event);
                    bizEventReplaceService.sendEmailForDoorAdmin(event);
                }
            }
        }
    }

    /**
     * 添加记录-取还柜不一致
     *
     * @param rfids
     * @param apiLog
     */
    private void addRecordForGoodsInWrongCab(List<String> rfids, DevApiLog apiLog) {
        //关门动作+不为空
        if (apiLog.getReqType() == 2 && !CollectionUtils.isEmpty(rfids)) {
            //查询对应配置
            BizEventConfig eventConfig = bizEventConfigMapper.selectById("17");
            List<BizGoods> goodsList = bizGoodsMapper.getListByRfids(rfids);
            //柜门信息
            String doorName = bizEventReplaceService.getCbaDoorNameForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            for (BizGoods goods : goodsList) {
                //未知物品可能没存放柜门
                if (StringUtils.isNotBlank(goods.getBioCabinetDoorId())) {
                    //这里只要判断2个柜门ID即可
                    if (!goods.getBioCabinetDoorId().equals(cabinetDoorResp.getId())) {
                        String eventDesc = eventConfig.getEventDesc();
                        String bioDoorName = bizEventReplaceService.getCbaDoorNameForId(goods.getBioCabinetId(), goods.getBioCabinetDoorId());
                        String goodsName = bizEventReplaceService.getGoodsNameForEntity(goods);
                        //事件描述
                        eventDesc = eventDesc.replace("{{goods}}", goodsName);
                        eventDesc = eventDesc.replace("{{bio-cab-door}}", bioDoorName);
                        eventDesc = eventDesc.replace("{{cur-cab-door}}", doorName);
                        eventDesc = eventDesc.replace("{{time}}", DateUtil.formatDateTime(apiLog.getEventTime()));
                        eventDesc = eventDesc.replace("{{action}}", EventActionUtil.getApiAction(apiLog.getReqType()));
                        String userName = bizEventReplaceService.getUserName(apiLog.getUserId());
                        eventDesc = eventDesc.replace("{{user}}", userName);
                        //组合实体类
                        BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
                        event.setApiLogId(apiLog.getId());
                        event.setEventConfigId(eventConfig.getId());
                        event.setEventTime(apiLog.getEventTime());
                        event.setEventDesc(eventDesc);
                        event.setEventUserId(apiLog.getUserId());
                        event.setGoodsId(goods.getId());
                        event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
                        event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
                        event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
                        event.setCabinetDoorId(cabinetDoorResp.getId());
                        bizEventReplaceService.clearBizEvent(event);
                        bizEventMapper.insert(event);

                        //【邮件+短信】本次刷卡开门的卡主，柜门管理员
                        bizEventReplaceService.sendEmailForUser(apiLog.getUserId(), event);
                        bizEventReplaceService.sendEmailForDoorAdmin(event);
                        Map<String, String> content = new HashMap<>();
                        content.put("item", goodsName);
                        content.put("errdoor", bioDoorName);
                        content.put("rightdoor", doorName);
                        content.put("time", DateUtil.formatDateTime(apiLog.getEventTime()));
                        content.put("action", EventActionUtil.getApiAction(apiLog.getReqType()));
                        content.put("user", userName);
                        bizEventReplaceService.sendSmsForUser(apiLog.getUserId(), event, AliyunSmsUtil.INCONSISTENT_WITHDRAWAL_RETURN, content);
                        bizEventReplaceService.sendSmsForDoorAdmin(event, AliyunSmsUtil.POWER_OFF_RESTART, content);
                    }
                }
            }
        }
    }

    /**
     * 处理-物品借用
     *
     * @param rfids
     * @param apiLog
     */
    private void handleGoodsBorrow(List<String> rfids, DevApiLog apiLog) {
        if (!CollectionUtils.isEmpty(rfids)) {
            //更新物品借出
            bizGoodsMapper.updateForLendByRfids(rfids);
            //获取商品信息
            List<BizGoods> goodsList = bizGoodsMapper.getListByRfids(rfids);
            //list-未知用户借用物品
            List<BizGoods> borUnkUserList = new ArrayList<>();
            //获取柜子信息
            BizCabinetDoorResp cabinetDoorResp = bizCabinetDoorMapper.getInfoByCabCodeAndCabDoorCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            //处理开始
            for (BizGoods goods : goodsList) {
                BizGoodsLedger goodsLedger = new BizGoodsLedger();
                goodsLedger.setApiLogId(apiLog.getId());
                goodsLedger.setLedgerType(10);
                goodsLedger.setGoodsId(goods.getId());
                goodsLedger.setCurCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
                goodsLedger.setCurCabinetId(cabinetDoorResp.getCabinetInfoId());
                goodsLedger.setCurCabinetDoorId(cabinetDoorResp.getId());
                goodsLedger.setDeliveryTime(apiLog.getEventTime());
                goodsLedger.setDeliveryUserId(apiLog.getUserId());
                goodsLedger.setReturnTime(bizGoodsService.getReturnTime(goods, apiLog.getEventTime()));
                goodsLedger.setReturnFlag(0);
                goodsLedger.setCreateUser(apiLog.getUserId());
                bizGoodsLedgerMapper.insert(goodsLedger);
                //记录对应检查项
                bizGoodsLedgerCheckService.addGoodsLedgerChecks(goods, goodsLedger);

                //非对称情况下 触发未知用户借用物品
                if (apiLog.getPariFlag() == 0) {
                    borUnkUserList.add(goods);
                } else {
                    //历史关联的api数据
                    if (StringUtils.isNotBlank(apiLog.getRelationIds())) {
                        List<DevApiLog> apiLogList = devApiLogMapper.getListByIds(Arrays.asList(apiLog.getRelationIds().split(",")));
                        for (DevApiLog logItem : apiLogList) {
                            // 断电重启+机械开门
                            if (logItem.getReqType() == 5 || (logItem.getReqType() == 1 && StringUtils.isBlank(logItem.getUserId()))) {
                                borUnkUserList.add(goods);
                            }
                        }
                    }
                    //历史关联的api数据
                    DevApiLog relationApiLog = devApiLogMapper.selectById(apiLog.getRelationId());
                    if (relationApiLog.getPariFlag() == 0 && StringUtils.isNotBlank(relationApiLog.getRelationId())) {
                        borUnkUserList.add(goods);
                    }
                    if (StringUtils.isBlank(apiLog.getUserId())) {
                        borUnkUserList.add(goods);
                    }
                }
                this.addRecordForGoodsBorOfUnkUser(borUnkUserList, apiLog);
            }
        }
    }

    /**
     * 处理-物品归还
     *
     * @param rfids
     * @param apiLog
     */
    private void handleForGoodsReturn(List<String> rfids, DevApiLog apiLog) {
        if (!CollectionUtils.isEmpty(rfids)) {
            List<BizGoods> goodsList = bizGoodsMapper.getListByRfids(rfids);
            //list-未知用户归还物品
            List<BizGoods> retUnkUserList = new ArrayList<>();
            //list-取还人不一致
            List<GoodsLedgerPageResult> brUserAbnList = new ArrayList<>();
            //list-物品超期归还
            List<GoodsLedgerPageResult> retOvdList = new ArrayList<>();
            //list-试剂列表
            List<BizGoods> reagentList = new ArrayList<>();
            //获取柜子信息
            BizCabinetDoorResp cabinetDoorResp = bizCabinetDoorMapper.getInfoByCabCodeAndCabDoorCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            //处理开始
            for (BizGoods goods : goodsList) {
                //查找未归还的物品台账
                GoodsLedgerPageResult goodsLedgerPageResult = bizGoodsLedgerMapper.getNydRecordForGoodsId(goods.getId());
                if (null != goodsLedgerPageResult) {
                    BizGoodsLedger goodsLedger = new BizGoodsLedger();
                    goodsLedger.setId(goodsLedgerPageResult.getId());
                    goodsLedger.setRetApiId(apiLog.getId());
                    goodsLedger.setRetCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
                    goodsLedger.setRetCabinetId(cabinetDoorResp.getCabinetInfoId());
                    goodsLedger.setRetCabinetDoorId(cabinetDoorResp.getId());
                    goodsLedger.setWarehouseTime(apiLog.getEventTime());
                    goodsLedger.setWarehouseUserId(apiLog.getUserId());
                    //试剂
                    if (goods.getGoodsType() == 1) {
                        //获取时间点之前的称重记录
                        DevApiLog devApiLog = devApiLogMapper.getLastOneForReagentWeigh(goods.getRfidNum(), apiLog.getEventTime());
                        //需要称重 判定——取还间称重次数小于两次
                        if (StringUtils.isNotBlank(goods.getReagentWeighNeedFlag())) {
                            if (goods.getReagentWeighNeedFlag().equals("1")) {
                                if (devApiLog == null || StringUtils.isBlank(goodsLedgerPageResult.getReagentOutApiId())) {
                                    //无称重记录 & 出库无称重记录
                                    reagentList.add(goods);
                                } else {
                                    if (StringUtils.isNotBlank(goodsLedgerPageResult.getReagentOutApiId()) && goodsLedgerPageResult.getReagentOutApiId().equals(devApiLog.getId())) {
                                        //出库和入库称重一致
                                        reagentList.add(goods);
                                    }
                                }
                            }
                        }
                        //处理入库数据
                        if (null != devApiLog) {
                            goodsLedger.setReagentRetApiId(devApiLog.getId());
                            String retWeight = devApiLog.getReagentWeight();
                            if (goods.getReagentContainerWeight() != null) {
                                //有容器重量时候计算毛重
                                retWeight = NumberUtil.round(NumberUtil.sub(retWeight, goods.getReagentContainerWeight().toString()), 2).toString();
                            }
                            goodsLedger.setReagentRetWeight(retWeight);
                            if (goods.getReagentDensity() != null) {
                                goodsLedger.setReagentRetVolume(NumberUtil.div(retWeight, goods.getReagentDensity().toString(), 2).toString());
                            }
                            if (StringUtils.isNotBlank(goodsLedgerPageResult.getReagentOutWeight())) {
                                //计算使用了多少
                                BigDecimal useWeight = NumberUtil.round(NumberUtil.sub(goodsLedgerPageResult.getReagentOutWeight(), retWeight), 2);
                                goodsLedger.setReagentUseWeight(useWeight.toString());
                                if (goods.getReagentDensity() != null) {
                                    goodsLedger.setReagentUseVolume(NumberUtil.div(useWeight, goods.getReagentDensity(), 2).toString());
                                }
                            }
                            //处理物品剩余量
                            bizGoodsService.handleReagentAvlData(goods, retWeight);
                        }
                    }
                    goodsLedger.setReturnFlag(1);
                    bizGoodsLedgerMapper.updateById(goodsLedger);
                    if (StringUtils.isBlank(apiLog.getUserId())) {
                        brUserAbnList.add(goodsLedgerPageResult);
                        retUnkUserList.add(goods);
                    } else {
                        if (!apiLog.getUserId().equals(goodsLedgerPageResult.getDeliveryUserId())) {
                            brUserAbnList.add(goodsLedgerPageResult);
                        }
                    }
                    if (DateUtil.between(goodsLedgerPageResult.getReturnTime(), apiLog.getEventTime(), DateUnit.SECOND, false) > 0) {
                        retOvdList.add(goodsLedgerPageResult);
                    }
                } else {
                    //没台账情况下 触发未知用户归还物品
                    if (apiLog.getPariFlag() == 0) {
                        retUnkUserList.add(goods);
                    } else {
                        //历史关联的api数据
                        if (StringUtils.isNotBlank(apiLog.getRelationIds())) {
                            List<DevApiLog> apiLogList = devApiLogMapper.getListByIds(Arrays.asList(apiLog.getRelationIds().split(",")));
                            for (DevApiLog logItem : apiLogList) {
                                // 断电重启+机械开门
                                if (logItem.getReqType() == 5 || (logItem.getReqType() == 1 && StringUtils.isBlank(logItem.getUserId()))) {
                                    retUnkUserList.add(goods);
                                }
                            }
                        }
                        if(StringUtils.isNotBlank(apiLog.getRelationId())){
                            //历史关联的api数据
                            DevApiLog relationApiLog = devApiLogMapper.selectById(apiLog.getRelationId());
                            if (relationApiLog.getPariFlag() == 0 && StringUtils.isNotBlank(relationApiLog.getRelationId())) {
                                retUnkUserList.add(goods);
                            }
                        }
                        if (StringUtils.isBlank(apiLog.getUserId())) {
                            retUnkUserList.add(goods);
                        }
                    }
                }
            }
            this.addRecordForGoodsRtnOfUnkUser(retUnkUserList, apiLog);
            this.addRecordForGoodsBrOfUserAbn(brUserAbnList, apiLog);
            this.addRecordForGoodsBrOfOverdue(retOvdList, apiLog);
            //试剂归还称重次数
            bizEventReagentService.handleRtnWeighCount(reagentList, apiLog);
        }
    }

    /**
     * 添加记录-未知用户归还物品
     *
     * @param goodsList
     * @param apiLog
     */
    private void addRecordForGoodsRtnOfUnkUser(List<BizGoods> goodsList, DevApiLog apiLog) {
        if (!CollectionUtils.isEmpty(goodsList)) {
            //去重
            goodsList = goodsList.stream().distinct().collect(Collectors.toList());
            //查询对应配置
            BizEventConfig eventConfig = bizEventConfigMapper.selectById("7");
            //柜门信息
            String doorName = bizEventReplaceService.getCbaDoorNameForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            for (BizGoods item : goodsList) {
                String eventDesc = eventConfig.getEventDesc();
                //事件描述
                eventDesc = eventDesc.replace("{{goods}}", bizEventReplaceService.getGoodsNameForEntity(item));
                eventDesc = eventDesc.replace("{{time}}", DateUtil.formatDateTime(apiLog.getEventTime()));
                eventDesc = eventDesc.replace("{{action}}", EventActionUtil.getApiAction(apiLog.getReqType()));
                //组合实体类
                BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
                event.setApiLogId(apiLog.getId());
                event.setEventConfigId(eventConfig.getId());
                event.setEventTime(apiLog.getEventTime());
                event.setEventDesc(eventDesc);
                event.setEventUserId(apiLog.getUserId());
                event.setGoodsId(item.getId());
                event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
                event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
                event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
                event.setCabinetDoorId(cabinetDoorResp.getId());
                bizEventReplaceService.clearBizEvent(event);
                //类目切换
                bizEventReplaceService.itemSwitch(event, item.getGoodsType());
                bizEventMapper.insert(event);

                //【邮件】柜门管理员
                bizEventReplaceService.sendEmailForDoorAdmin(event);
            }
        }
    }

    /**
     * 添加记录-取还人不一致
     *
     * @param ledgerPageResultList
     * @param apiLog
     */
    private void addRecordForGoodsBrOfUserAbn(List<GoodsLedgerPageResult> ledgerPageResultList, DevApiLog apiLog) {
        if (!CollectionUtils.isEmpty(ledgerPageResultList)) {
            //去重
            ledgerPageResultList = ledgerPageResultList.stream().distinct().collect(Collectors.toList());
            //查询对应配置
            BizEventConfig eventConfig = bizEventConfigMapper.selectById("18");
            //柜门信息
            String doorName = bizEventReplaceService.getCbaDoorNameForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            for (GoodsLedgerPageResult item : ledgerPageResultList) {
                String eventDesc = eventConfig.getEventDesc();
                //事件描述
                eventDesc = eventDesc.replace("{{goods}}", bizEventReplaceService.getGoodsNameForLedger(item));
                eventDesc = eventDesc.replace("{{borrower}}", bizEventReplaceService.getUserName(item.getDeliveryUserId()));
                eventDesc = eventDesc.replace("{{returnees}}", bizEventReplaceService.getUserName(apiLog.getUserId()));
                eventDesc = eventDesc.replace("{{action}}", EventActionUtil.getApiAction(apiLog.getReqType()));
                eventDesc = eventDesc.replace("{{time}}", DateUtil.formatDateTime(apiLog.getEventTime()));
                eventDesc = eventDesc.replace("{{user}}", bizEventReplaceService.getUserName(apiLog.getUserId()));
                //组合实体类
                BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
                event.setApiLogId(apiLog.getId());
                event.setEventConfigId(eventConfig.getId());
                event.setEventTime(apiLog.getEventTime());
                event.setEventDesc(eventDesc);
                event.setEventUserId(apiLog.getUserId());
                event.setGoodsId(item.getGoodsId());
                event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
                event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
                event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
                event.setCabinetDoorId(cabinetDoorResp.getId());
                bizEventReplaceService.clearBizEvent(event);
                bizEventMapper.insert(event);

                //【邮件】本次刷卡开门的卡主，柜门管理员，借用人
                bizEventReplaceService.sendEmailForUser(apiLog.getUserId(), event);
                bizEventReplaceService.sendEmailForDoorAdmin(event);
                bizEventReplaceService.sendEmailForUser(item.getDeliveryUserId(), event);
            }
        }
    }

    /**
     * 添加记录-物品超期归还
     *
     * @param ledgerPageResultList
     * @param apiLog
     */
    private void addRecordForGoodsBrOfOverdue(List<GoodsLedgerPageResult> ledgerPageResultList, DevApiLog apiLog) {
        if (!CollectionUtils.isEmpty(ledgerPageResultList)) {
            //去重
            ledgerPageResultList = ledgerPageResultList.stream().distinct().collect(Collectors.toList());
            //查询对应配置
            BizEventConfig eventConfig = bizEventConfigMapper.selectById("20");
            //柜门信息
            String doorName = bizEventReplaceService.getCbaDoorNameForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            for (GoodsLedgerPageResult item : ledgerPageResultList) {
                String eventDesc = eventConfig.getEventDesc();
                //事件描述
                eventDesc = eventDesc.replace("{{goods}}", bizEventReplaceService.getGoodsNameForLedger(item));
                eventDesc = eventDesc.replace("{{ret-time}}", DateUtil.formatDateTime(item.getReturnTime()));
                eventDesc = eventDesc.replace("{{act-ret-time}}", DateUtil.formatDateTime(apiLog.getEventTime()));
                //超期时间
                String ovdStr = DateUtil.formatBetween(item.getReturnTime(), apiLog.getEventTime(), BetweenFormatter.Level.SECOND);
                eventDesc = eventDesc.replace("{{ovd-hour}}", ovdStr);
                eventDesc = eventDesc.replace("{{action}}", EventActionUtil.getApiAction(apiLog.getReqType()));
                eventDesc = eventDesc.replace("{{time}}", DateUtil.formatDateTime(apiLog.getEventTime()));
                eventDesc = eventDesc.replace("{{user}}", bizEventReplaceService.getUserName(apiLog.getUserId()));
                //组合实体类
                BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
                event.setApiLogId(apiLog.getId());
                event.setEventConfigId(eventConfig.getId());
                event.setEventTime(apiLog.getEventTime());
                event.setEventDesc(eventDesc);
                event.setEventUserId(apiLog.getUserId());
                event.setGoodsId(item.getGoodsId());
                event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
                event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
                event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
                event.setCabinetDoorId(cabinetDoorResp.getId());
                event.setEventUserId(item.getDeliveryUserId());
                bizEventReplaceService.clearBizEvent(event);
                //类目切换
                bizEventReplaceService.itemSwitch(event, item.getGoodsType());
                bizEventMapper.insert(event);

                //【邮件】借用人，柜门管理员
                bizEventReplaceService.sendEmailForUser(item.getDeliveryUserId(), event);
                bizEventReplaceService.sendEmailForDoorAdmin(event);
            }
        }
    }

    /**
     * 添加记录-未知用户借用物品
     *
     * @param goodsList
     * @param apiLog
     */
    private void addRecordForGoodsBorOfUnkUser(List<BizGoods> goodsList, DevApiLog apiLog) {
        if (!CollectionUtils.isEmpty(goodsList)) {
            //去重
            goodsList = goodsList.stream().distinct().collect(Collectors.toList());
            //查询对应配置
            BizEventConfig eventConfig = bizEventConfigMapper.selectById("8");
            //柜门信息
            String doorName = bizEventReplaceService.getCbaDoorNameForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            BizCabinetDoorResp cabinetDoorResp = bizEventReplaceService.getCbaDoorRespForCode(apiLog.getCabinetCode(), apiLog.getCabinetDoorCode());
            for (BizGoods goods : goodsList) {
                String eventDesc = eventConfig.getEventDesc();
                //事件描述
                eventDesc = eventDesc.replace("{{goods}}", bizEventReplaceService.getGoodsNameForEntity(goods));
                eventDesc = eventDesc.replace("{{action}}", EventActionUtil.getApiAction(apiLog.getReqType()));
                eventDesc = eventDesc.replace("{{time}}", DateUtil.formatDateTime(apiLog.getEventTime()));
                //组合实体类
                BizEvent event = BeanUtil.toBean(eventConfig, BizEvent.class);
                event.setApiLogId(apiLog.getId());
                event.setEventConfigId(eventConfig.getId());
                event.setEventTime(apiLog.getEventTime());
                event.setEventDesc(eventDesc);
                event.setEventUserId(apiLog.getUserId());
                event.setGoodsId(goods.getId());
                event.setEventAction(EventActionUtil.getEventAction(apiLog.getReqType()));
                event.setCabinetGroupId(cabinetDoorResp.getCabinetGroupId());
                event.setCabinetId(cabinetDoorResp.getCabinetInfoId());
                event.setCabinetDoorId(cabinetDoorResp.getId());
                bizEventReplaceService.clearBizEvent(event);
                //类目切换
                bizEventReplaceService.itemSwitch(event, goods.getGoodsType());
                bizEventMapper.insert(event);

                //【邮件】柜门管理员
                bizEventReplaceService.sendEmailForDoorAdmin(event);
            }
        }
    }
}
